//
// Created by Zsir on 2025/8/22.
//
#ifndef EVENTLOOP_H
#define EVENTLOOP_H

#include <atomic>
#include <functional>
#include <vector>
#include <memory>
#include <mutex>
#include <thread>

class Channel;
class EpollPoller;

class EventLoop {
public:
    using Functor = std::function<void()>;

    EventLoop();
    ~EventLoop();

    void loop();
    void quit();
    void runInLoop(Functor cb);
    void queueInLoop(Functor cb);

    void updateChannel(Channel* channel);
    void removeChannel(Channel* channel);

    bool isInLoopThread() const;
    void assertInLoopThread();

private:
    void handleWakeup();
    void doPendingFunctors();
    void wakeup();

    std::atomic<bool> looping_;
    std::atomic<bool> quit_;
    std::atomic<bool> callingPendingFunctors_;

    const std::thread::id threadId_;
    std::unique_ptr<EpollPoller> poller_;

    int wakeupFd_;
    std::unique_ptr<Channel> wakeupChannel_;

    std::vector<Functor> pendingFunctors_;
    std::mutex mutex_;
};

#endif // EVENTLOOP_H